#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <string>

using namespace std;

//检查两个字符串是否几乎相等
//https://leetcode.cn/problems/check-whether-two-strings-are-almost-equivalent/submissions/
class Solution {
public:
    bool checkAlmostEquivalent(string word1, string word2) {
        unordered_map<char, int> m1;
        unordered_map<char, int> m2;

        for (const auto& x : word1) ++m1[x];
        for (const auto& x : word2) ++m2[x];

        unordered_set<char> s;
        for (const auto& x : m1) s.insert(x.first);
        for (const auto& x : m2) s.insert(x.first);


        for (const auto& x : s)
        {
            int diff = m2.count(x) == 0 ? m1[x] : m1[x] - m2[x];
            if (diff > 3 || diff < -3) return false;
        }
        return true;
    }
};


//字符串解码
//https://leetcode.cn/problems/decode-string/
class Solution {
public:
    stack<int> st;
    int pos = 0;

    string decodeString(string s) {
        string ret;
        while (pos < s.size())
        {
            if (s[pos] >= '0' && s[pos] <= '9')
            {
                int num = s[pos++] - '0';
                while (s[pos] >= '0' && s[pos] <= '9')
                {
                    num = (num * 10) + (s[pos] - '0');
                    ++pos;
                }
                st.push(num);
            }
            else if (s[pos] >= 'a' && s[pos] <= 'z') ret.push_back(s[pos++]);
            else if (s[pos] == '[')
            {
                ++pos;
                ret += decodeString(s);
            }
            else if (s[pos] == ']')
            {
                ++pos;
                break;
            }
        }
        int multiple = 1;
        if (st.size())
        {
            multiple = st.top();
            st.pop();
        }
        string tmp;
        tmp.reserve(multiple * ret.size());
        while (multiple--) tmp += ret;

        return tmp;
    }
};